package game;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;

import datastructures.Word;

/**
 * 
 * @author Fredrik
 *
 */
public class WordDialog extends JDialog implements PropertyChangeListener,
		ActionListener {
	/**
	 * 
	 */
	private static final long serialVersionUID = 6445719240446611191L;
	
	private String okButtonTxt = "OK";
	private String cancelButtonTxt = "Cancel";


	private final static String ADD_WORD_ACTION = "ADD_WORD";
	private final static String DELETE_WORD_ACTION = "DELETE_WORD";
	

	private JPanel dataPanel = new JPanel();
	private JTextField wordField = new JTextField(20);
	private JTextField associateField = new JTextField(20);
	private JButton buttonDeleteAssociat = new JButton("Delete spelling");
	private JButton buttonAssociate = new JButton("Add word");
	private JList listAssociates = new JList();
	private JCheckBox isMiddleCheckBox = new JCheckBox("Is middle");
	private JCheckBox isTaken = new JCheckBox("Is Taken");


	private JOptionPane optionPane = new JOptionPane("Create a new word");
	private ArrayList<String> associates = new ArrayList<String>();
	

	private Word word;
	
	private boolean cancel = true;

	/**
	 * Constructor creating a new word dialog
	 * @param aFrame
	 * @param show
	 * @param word
	 */
	public WordDialog(JFrame aFrame, boolean show,
			Word word) {
		super(aFrame, show);
		this.word = word;
		init();
	}

	/**
	 * Constructor creating a new word dialog
	 * @param word
	 */
	public WordDialog(Word word) {
		this.word = word;
		init();

	}

	private void init() {
		setTitle("Edit word");
		this.wordField.setText(this.word.getWordText());
		this.associates.addAll(this.word.getAssociates());
		this.isMiddleCheckBox.setSelected(this.word.isMiddle());


		JLabel labelWord = new JLabel("Word:");
		JLabel labelSpelling = new JLabel("Add different spelling:");

		this.buttonAssociate.setActionCommand(ADD_WORD_ACTION);
		this.buttonDeleteAssociat.setActionCommand(DELETE_WORD_ACTION);
		this.buttonAssociate.addActionListener(this);
		this.buttonDeleteAssociat.addActionListener(this);

		this.listAssociates.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.listAssociates.setLayoutOrientation(JList.VERTICAL);
		this.listAssociates.setVisibleRowCount(-1);
		this.listAssociates.setListData(this.associates.toArray());

		JScrollPane listScroller = new JScrollPane(this.listAssociates);
		listScroller.setPreferredSize(new Dimension(250, 80));

		this.dataPanel.setLayout(new GridBagLayout());
		
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 0;
		c.weighty = 0.5;

		this.dataPanel.add(labelWord, c);
		c.gridy++;
		this.dataPanel.add(this.wordField, c);
		c.gridy++;
		this.dataPanel.add(labelSpelling, c);
		c.gridy++;
		this.dataPanel.add(this.associateField, c);
		c.gridy++;
		this.dataPanel.add(this.buttonAssociate, c);
		c.gridy++;
		this.dataPanel.add(this.isMiddleCheckBox, c);
		c.gridy++;
		this.dataPanel.add(this.isTaken, c);

		c.gridx = 1;
		c.gridy = 0;
		c.gridheight = 4;

		this.dataPanel.add(listScroller, c);
		c.gridy = 4;
		c.gridheight = 1;
		this.dataPanel.add(this.buttonDeleteAssociat, c);


		Object[] array = { this.dataPanel };
		Object[] options = { this.okButtonTxt, this.cancelButtonTxt };

		this.optionPane = new JOptionPane(array, JOptionPane.PLAIN_MESSAGE,
				JOptionPane.YES_NO_OPTION, null, options, options[0]);

		// Make this dialog display it.
		setContentPane(this.optionPane);

		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

		pack();

		addComponentListener(new ComponentAdapter() {
			@Override
			public void componentShown(ComponentEvent ce) {
				WordDialog.this.wordField.requestFocusInWindow();
			}
		});

		this.optionPane.addPropertyChangeListener(this);
		


	}

	
	/** (non-Javadoc)
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent e) {
		String prop = e.getPropertyName();

		if (isVisible()
				&& (e.getSource() == this.optionPane)
				&& (JOptionPane.VALUE_PROPERTY.equals(prop) || JOptionPane.INPUT_VALUE_PROPERTY
						.equals(prop))) {
			Object value = this.optionPane.getValue();

			if (value == JOptionPane.UNINITIALIZED_VALUE) {
				// ignore reset
				return;
			}

			this.optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);

			if (this.okButtonTxt.equals(value)) {
				if (this.wordField.getText().length() > 0) {
					this.word.setWord(this.wordField.getText());
					
					this.word.setAssociates(this.associates);
					this.word.setIsMiddle(this.isMiddleCheckBox.isSelected());
					this.word.setIsTaken(this.isTaken.isSelected());
					
					this.cancel = false;
					setVisible(false);
				}
			} else {
				setVisible(false);
			}

		}

	}
	
	/**
	 * returns true if cancel was chosen
	 * @return true if cancel was chosen
	 */
	public boolean isCancel(){
		return this.cancel;
	}

	/**
	 * Returns the word that is edited
	 * @return the word that is edited
	 */
	public Word getWord() {
		return this.word;
	}

	
	/** (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals(ADD_WORD_ACTION)) {
			String wordToAdd = this.associateField.getText().toLowerCase();
			this.associateField.setText("");
			if (!this.associates.contains(wordToAdd) && wordToAdd.length()>0) {
				this.associates.add(wordToAdd);
				this.listAssociates.setListData(this.associates.toArray());
			}
		} else if (e.getActionCommand().equals(DELETE_WORD_ACTION)) {
			String deleteAssociate = (String) this.listAssociates.getSelectedValue();
			this.associates.remove(deleteAssociate);
			this.listAssociates.setListData(this.associates.toArray());
		}

	}

	

	

}
